package com.apache.workday;

import com.apache.tools.ConfigUtil;
import com.apache.tools.LogUtil;
import com.apache.tools.StrUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.text.Collator;
import java.util.*;

/**
 * 工作日service
 *
 * @version 1.2.3
 */
public class WorkdayService {

    private static Logger log = LoggerFactory.getLogger(WorkdayService.class);

    /**
     * 保存文件路径
     */
    private String filePathName;// = "d:\\workday_config.json";

    private static final String fileName = "workday_config.json";

    /**
     * 日期map
     */
    private Map<String, Workday> dayMap = new LinkedHashMap<String, Workday>();

    /**
     * 日期list
     */
    private List<Workday> dayList = new ArrayList<Workday>();

    /**
     * 构造器
     *
     * @param filePathName
     */
    public WorkdayService(String filePathName) {
        if (StrUtil.isNotNull(filePathName) && filePathName.indexOf(".jar") == -1) {
            if (!filePathName.endsWith(File.separator) && !filePathName.endsWith("/"))
                filePathName += "/";
        }
        this.filePathName = filePathName;
        this.initFromFile();

    }

    /**
     * 把config/workday_config.json下的数据添加到dayList和dayMap中
     */
    private void initFromFile() {
        String jsonString = readFile(filePathName);
        if (jsonString != null && false == "".equals(jsonString.trim())) {
            JSONArray array = JSONArray.fromObject(jsonString);
            for (int i = 0; i < array.size(); i++) {
                JSONObject jsonObject = (JSONObject) array.getJSONObject(i);
                Workday dvo = (Workday) JSONObject.toBean(jsonObject, Workday.class);
                dayMap.put(dvo.getDateStr(), dvo);
                dayList.add(dvo);
            }
        }
    }

    /**
     * 保存
     *
     * @param newDay
     */
    //@Deprecated
    @SuppressWarnings({ "unchecked", "static-access" })
    private void saveDayOld(Workday newDay) {
        String rmOrup = ConfigUtil.getInstance().getValueByKey("rmOrup");
        rmOrup = StrUtil.doNull(rmOrup, "0");
        //update
        if ("0".equals(rmOrup)) {
            // 删除list中旧的
            for (int i = 0; i < dayList.size(); i++) {
                Workday dvo = (Workday) dayList.get(i);
                if (dvo.getDateStr().equals(newDay.getDateStr())) {
                    dayList.remove(i);
                }
            }
            this.dayMap.put(newDay.getDateStr(), newDay);
            this.dayList.add(newDay);

            Collections.sort(dayList, new DayCompara(true));

            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < dayList.size(); i++) {
                Workday dvo = (Workday) dayList.get(i);
                String temp = JSONObject.fromObject(dvo).toString();
                if (i != 0) {
                    sb.append(",").append("\r\n");
                }
                sb.append(temp);
            }
            String str = "";
            if (sb.length() > 0) {
                str = "[\r\n" + sb.toString() + "\r\n]";
            }

            // JSONArray.fromObject(dayList).toString()
            this.newFile(this.filePathName + fileName, str);
            //remove
        } else if ("1".equals(rmOrup)) {
            // 删除list中旧的
            if (newDay.getIsWorkday().equals("T")) {
                for (int i = 0; i < dayList.size(); i++) {
                    Workday dvo = (Workday) dayList.get(i);
                    if (dvo.getDateStr().equals(newDay.getDateStr())) {
                        dayList.remove(i);
                    }
                }
                this.dayMap.remove(newDay.getDateStr());
            } else {
                this.dayMap.put(newDay.getDateStr(), newDay);
                //添加新的
                this.dayList.add(newDay);
            }

            Collections.sort(dayList, new DayCompara(true));
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < dayList.size(); i++) {
                Workday dvo = (Workday) dayList.get(i);
                String temp = JSONObject.fromObject(dvo).toString();
                if (i != 0) {
                    sb.append(",").append("\r\n");
                }
                sb.append(temp);
            }
            String str = "";
            if (sb.length() > 0) {
                str = "[\r\n" + sb.toString() + "\r\n]";
            }

            // JSONArray.fromObject(dayList).toString()
            this.newFile(this.filePathName + fileName, str);
        }

    }

    /**
     * 排序规则
     */
    @SuppressWarnings("rawtypes")
    private static class DayCompara implements Comparator {

        static Comparator cmp = Collator.getInstance(java.util.Locale.CHINA);

        boolean isASC = true;// 默认升序

        public DayCompara(boolean isAsc) {
            this.isASC = isAsc;
        }

        @SuppressWarnings("unchecked")
        public int compare(Object o1, Object o2) {

            Workday a = (Workday) o1;
            Workday b = (Workday) o2;

            String dataStrA = a.getDateStr();
            String dataStrB = b.getDateStr();

            int t = cmp.compare(dataStrA, dataStrB);
            // int t = nameA.compareToIgnoreCase(nameB);
            return isASC ? t : (-t);
        }
    }

    /**
     * 读入工作日文件
     *
     * @param filePath 工作日文件的路径  /config/workday_config.json
     * @return String
     */
    private static String readFile(String filePath) {
        StringBuffer sb = new StringBuffer();
        BufferedReader br = null;
        FileReader read = null;
        try {
            if (filePath.indexOf(".jar") != -1) {
                InputStreamReader inputStreamReader = new InputStreamReader(WorkdayService.class.
                        getClassLoader().getResourceAsStream("config/" + fileName));
                br = new BufferedReader(inputStreamReader);
            } else {
                read = new FileReader(filePath + fileName);
                br = new BufferedReader(read);
            }

            String row = "";
            while ((row = br.readLine()) != null) {
                sb.append(row);
            }
        } catch (Exception e) {
            LogUtil.error("readFile file error!" + e);
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(br);
            IOUtils.closeQuietly(read);
        }

        return sb.toString();
    }

    /**
     * 重新写文件
     *
     * @param filePathAndName 文件路径  /config/workday_config.json
     * @param fileContent 文件内容
     */
    private static void newFile(String filePathAndName, String fileContent) {
        FileWriter resultFile = null;
        PrintWriter myFile = null;
        try {
            String filePath = filePathAndName;

            File myFilePath = new File(filePath);
            if (!myFilePath.exists()) {
                myFilePath.createNewFile();
            }
            resultFile = new FileWriter(myFilePath);
            myFile = new PrintWriter(resultFile);

            String strContent = fileContent;
            myFile.println(strContent);
        } catch (Exception e) {
            log.error("new file error!" + e);
        } finally {
            IOUtils.closeQuietly(myFile);
            IOUtils.closeQuietly(resultFile);
        }

    }

    /**
     * 取到某年下的数据
     *
     * @param year 格式yyyy 例如getDayListOfYear("2012");
     * @return
     */
    public List<Workday> getDayListOfYear(String year) {
        List<Workday> list = new ArrayList<Workday>();
        for (int i = 0; i < dayList.size(); i++) {
            Workday vo = dayList.get(i);
            if (vo.getDateStr().startsWith(year)) {
                list.add(vo);
            }

        }
        return list;
    }

    public List<Workday> getDayList() {
        return dayList;
    }

    public Map<String, Workday> getDayMap() {
        return dayMap;
    }

    public void setDay(Workday dvo) {
        this.saveDayOld(dvo);
    }

    public Workday getDay(String yyyyMMdd) {
        return this.dayMap.get(yyyyMMdd);
    }
    // -----------------------------------------------

    // public String day2JsonStr(Workday dvo){
    // return "
    // {\"updateTime\":\"\",\"dateStr\":\"20110204\",\"isWorkDay\":false,\"updateUser\":\"\"}";
    // }
    // private static JSONObject Day2JsonObj(Workday dvo) {
    // JSONObject jvo = new JSONObject();
    //
    // jvo.put("dateStr", dvo.getDateStr());
    // jvo.put("isWorkDay", dvo.isWorkday());
    // jvo.put("updateUser", dvo.getUpdateTime());
    // jvo.put("updateTime", dvo.getUpdateTime());
    // jvo.put("remark", dvo.getRemark());
    // return jvo;
    // }
    // private static Workday jsonObj2DayVo(JSONObject jvo){
    // Workday dvo = new Workday();
    // dvo.setDateStr(jvo.getString("dateStr"));
    // dvo.setWorkday(jvo.getBoolean("isWorkDay"));
    // dvo.setRemark(jvo.getString("remark"));
    // dvo.setUpdateTime(jvo.getString("updateTime"));
    // dvo.setUpdateUser(jvo.getString("updateUser"));
    // return dvo;
    // }

}
